package com.fzy.common.template;

import com.fzy.common.file.FileUtil;
import freemarker.template.*;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Map;

/**
 * Freemarker应用类. 根据模板生成文件.
 */
public class FreemarkerUtil {


    private FreemarkerUtil() {
    }

    private static Configuration freemarkerCfg = null;

    private static Logger log = LoggerFactory.getLogger(FreemarkerUtil.class);

    public static String templateRootPath;

    public static String root;

    /**
     * 初始化模板路径
     *
     * @param realPath 模板根路径,在InitServlet中初始化
     */
    public static void initPath(String realPath, String rootPath) {
        templateRootPath = realPath;
        root = rootPath;
    }

    /**
     * 获取freemarker的配置. freemarker本身支持classpath,目录和从ServletContext获取.
     */
    protected static Configuration getFreeMarkerConfig() throws IOException {
        if (null == freemarkerCfg) {
            // Initialize the FreeMarker configuration;
            // - Create a configuration instance
            freemarkerCfg = new Configuration();

            // - FreeMarker支持多种模板装载方式,可以查看API文档,都很简单:路径,根据Servlet上下文,classpath等等
            log.debug(templateRootPath);
            // htmlskin是放在classpath下的一个目录
            // freemarkerCfg.setClassForTemplateLoading(this.getClass(), "");
            freemarkerCfg.setDirectoryForTemplateLoading(new File(
                    templateRootPath));
            freemarkerCfg.setObjectWrapper(new DefaultObjectWrapper());
            freemarkerCfg.setDefaultEncoding("UTF-8");
        }

        return freemarkerCfg;
    }

    /**
     * 生成静态文件.
     *
     * @param templateFileName 模板文件名,相对htmlskin路径,例如"/tpxw/view.ftl"
     * @param propMap          用于处理模板的属性Object映射
     * @param htmlFilePath     要生成的静态文件的路径,相对设置中的根路径,例如 "/tpxw/1/2005/4/1.htm"
     */
    public static boolean generateFile(String templateFileName, Map propMap,
                                       String htmlFilePath) {
        String htmlFileDir = htmlFilePath.substring(0, htmlFilePath
                .lastIndexOf(File.separator));
        //生成目录,linux必须是正斜杠
        htmlFileDir = htmlFileDir.replace("\\", "/");
        String htmlFileName = htmlFilePath.substring(htmlFilePath
                .lastIndexOf(File.separator) + 1);
        try {
            Template t = getFreeMarkerConfig().getTemplate(templateFileName);
            t.setEncoding("UTF-8");
            // 递归创建子目录
            FileUtil.mkdirs(htmlFilePath);

            File afile = new File(htmlFilePath);

            Writer out = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(afile), "UTF-8"));
            propMap.put("root", root);
            t.process(propMap, out);
        } catch (TemplateException e) {
            log.error("Error while processing FreeMarker template "
                    + templateFileName, e);
            return false;
        } catch (IOException e) {
            log.error("Error while generate Static Html File " + htmlFileName,
                    e);
            return false;
        }

        return true;
    }


    /**
     * @description 获取模板
     */
    public static String getContent(String fileName, Object data) throws Exception {

        String templatePath = getPDFTemplatePath(fileName);
        String templateFileName = getTemplateName(templatePath);
        String templateFilePath = getTemplatePath(templatePath);
        if (StringUtils.isEmpty(templatePath)) {

            throw new Exception("templatePath can not be empty!");
        }
        try {
            Configuration config = new Configuration();
            config.setDefaultEncoding("UTF-8");
            config.setDirectoryForTemplateLoading(new File(templateFilePath));
            config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
            //config.setLogTemplateExceptions(false);
            Template template = config.getTemplate(templateFileName);
            StringWriter writer = new StringWriter();
            template.process(data, writer);
            writer.flush();
            String html = writer.toString();
            return html;
        } catch (Exception ex) {
            throw new Exception("FreeMarkerUtil process fail", ex);
        }
    }

    private static String getTemplatePath(String templatePath) {
        if (StringUtils.isEmpty(templatePath)) {
            return "";
        }
        String path = templatePath.substring(0, templatePath.lastIndexOf(File.separator));
        return path;
    }

    private static String getTemplateName(String templatePath) {
        if (StringUtils.isEmpty(templatePath)) {
            return "";
        }
        String fileName = templatePath.substring(templatePath.lastIndexOf(File.separator) + 1);
        return fileName;
    }

    /**
     * @description 获取PDF的模板路径,
     * 默认按照PDF文件名匹对应模板
     * @param fileName PDF文件名    (hello.pdf)
     * @return         匹配到的模板名
     */
    public static String getPDFTemplatePath(String fileName) throws Exception {
        String classpath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
        String templatePath = classpath + "/templates/";
        File file = new File(templatePath);
        if (!file.isDirectory()) {
            throw new Exception("PDF模板文件不存在,请检查templates文件夹!");
        }
        String pdfFileName = fileName.substring(0, fileName.lastIndexOf("."));
        File defaultTemplate = null;
        File matchTemplate = null;
        for (File f : file.listFiles()) {
            if (!f.isFile()) {
                continue;
            }
            String templateName = f.getName();
            if (templateName.lastIndexOf(".ftl") == -1) {
                continue;
            }
            if (defaultTemplate == null) {
                defaultTemplate = f;
            }
            if (StringUtils.isEmpty(fileName) && defaultTemplate != null) {
                break;
            }
            templateName = templateName.substring(0, templateName.lastIndexOf("."));
            if (templateName.toLowerCase().equals(pdfFileName.toLowerCase())) {
                matchTemplate = f;
                break;
            }
        }
        if (matchTemplate != null) {
            return matchTemplate.getAbsolutePath();
        }
        if (defaultTemplate != null) {
            return defaultTemplate.getAbsolutePath();
        }

        return null;

    }

    public static void main(String[] args) {
    }

}
